package com.iwhalecloud.bss.kite.cucc.service.attr;

import com.iwhalecloud.bss.kite.client.vo.scene.CommonAttrVO;
import com.iwhalecloud.bss.kite.common.constant.KeyConsts;
import com.iwhalecloud.bss.kite.common.constant.SymbolConsts;
import com.iwhalecloud.bss.kite.common.util.*;
import com.iwhalecloud.bss.kite.cucc.client.api.attr.IUnicomRegionService;
import com.iwhalecloud.bss.kite.cucc.client.dto.attr.UnicomRegion;
import com.iwhalecloud.bss.kite.cucc.client.dto.attr.UnicomRegionQry;
import com.iwhalecloud.bss.kite.cucc.common.constant.LocalKeyConsts;
import com.iwhalecloud.bss.kite.dataservice.cache.DcPublicCache;
import com.iwhalecloud.bss.kite.dataservice.entity.DcPublic;
import com.iwhalecloud.bss.kite.manager.api.IOperateSceneInstService;
import com.iwhalecloud.bss.kite.manager.api.IQuerySceneInstService;
import com.iwhalecloud.bss.kite.manager.inst.KiteAttr;
import com.iwhalecloud.bss.kite.manager.inst.KiteAttrValue;
import com.iwhalecloud.bss.kite.manager.inst.KiteInst;
import com.iwhalecloud.bss.kite.manager.inst.KiteOfferInst;
import com.iwhalecloud.bss.kite.manager.inst.KiteSceneInst;
import com.iwhalecloud.bss.kite.service.scene.attr.OperateInstAttrService;
import com.ztesoft.bss.base.entity.StaticAttrDO;
import com.ztesoft.bss.common.util.SpringUtil;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @ClassName : LocalAttrHelper
 * @Description : 属性助手
 * @Author : xie.zhengjun
 * @Date : 2020/9/22 23:04
 */
public class LocalAttrHelper {
    /**
     * 初始化可选省份
     *
     * @param attr
     */
    public static void initProvince(KiteAttr attr) {
        IUnicomRegionService unicomRegionService = KiteSpringUtils.getBeanHighPriority(IUnicomRegionService.class);
        List<UnicomRegion> unicomRegions = unicomRegionService.listSubRegion("");
        if (KiteListUtils.isEmpty(unicomRegions)) {
            return;
        }
        List<KiteAttrValue> kiteAttrValues = unicomRegions.stream().map(unicomRegion -> {
            KiteAttrValue kiteAttrValue = new KiteAttrValue();
            kiteAttrValue.setAttrValue(unicomRegion.getRegionCode());
            kiteAttrValue.setAttrValueName(unicomRegion.getRegionName());
            return kiteAttrValue;
        }).collect(Collectors.toList());

        attr.setAttrValues(kiteAttrValues);
    }

    /**
     * 加载可选城市
     *
     * @param provinceCode
     * @param city
     */
    public static void loadCity(String provinceCode, KiteAttr city) {
        if (KiteStringUtils.isNotEmpty(provinceCode)) {
            IUnicomRegionService unicomRegionService = KiteSpringUtils.getBeanHighPriority(IUnicomRegionService.class);
            List<UnicomRegion> unicomRegions = unicomRegionService.listSubRegion(provinceCode);
            if (KiteListUtils.isEmpty(unicomRegions)) {
                return;
            }
            List<KiteAttrValue> kiteAttrValues = unicomRegions.stream().map(unicomRegion -> {
                KiteAttrValue kiteAttrValue = new KiteAttrValue();
                kiteAttrValue.setAttrValue(unicomRegion.getRegionCode());
                kiteAttrValue.setAttrValueName(unicomRegion.getRegionName());
                return kiteAttrValue;
            }).collect(Collectors.toList());

            city.setAttrValues(kiteAttrValues);
        }
        else {
            city.setAttrValues(new ArrayList<>());
        }
    }

    /**
     * 设置某个属性必填
     *
     * @param inst
     * @param fieldName
     */
    public static void setNonnull(KiteInst inst, String fieldName) {
        KiteAttr kiteAttr = inst.getAttr(fieldName);
        if (Objects.nonNull(kiteAttr)) {
            kiteAttr.setIsNull(KeyConsts.IFTRUE_F);
        }
    }

    /**
     * 设置某个属性非必填
     *
     * @param inst
     * @param fieldName
     */
    public static void setNullable(KiteInst inst, String fieldName) {
        KiteAttr kiteAttr = inst.getAttr(fieldName);
        if (Objects.nonNull(kiteAttr)) {
            kiteAttr.setIsNull(KeyConsts.IFTRUE_T);
        }
    }

    /**
     * 设置某个属性可编辑
     *
     * @param inst
     * @param fieldName
     */
    public static void setEditable(KiteInst inst, String fieldName) {
        KiteAttr kiteAttr = inst.getAttr(fieldName);
        if (Objects.nonNull(kiteAttr)) {
            kiteAttr.setIsEdit(KeyConsts.IFTRUE_T);
        }
    }

    /**
     * 设置多个属性可编辑
     *
     * @param inst
     * @param fieldNames
     */
    public static void setMultipleEditable(KiteInst inst, String... fieldNames) {
        Arrays.asList(fieldNames).stream().forEach(fieldName -> {
            KiteAttr kiteAttr = inst.getAttr(fieldName);
            if (Objects.nonNull(kiteAttr)) {
                kiteAttr.setIsEdit(KeyConsts.IFTRUE_T);
            }
        });
    }

    /**
     * 设置某个属性不可编辑
     *
     * @param inst
     * @param fieldName
     */
    public static void setNotEditable(KiteInst inst, String fieldName) {
        KiteAttr kiteAttr = inst.getAttr(fieldName);
        if (Objects.nonNull(kiteAttr)) {
            kiteAttr.setIsEdit(KeyConsts.IFTRUE_F);
        }
    }

    /**
     * 设置多个属性不可编辑
     *
     * @param inst
     * @param fieldNames
     */
    public static void setMultipleNotEditable(KiteInst inst, String... fieldNames) {
        Arrays.asList(fieldNames).stream().forEach(fieldName -> {
            KiteAttr kiteAttr = inst.getAttr(fieldName);
            if (Objects.nonNull(kiteAttr)) {
                kiteAttr.setIsEdit(KeyConsts.IFTRUE_F);
            }
        });
    }

    public static String getRegionName(String regionCode) {
        IUnicomRegionService unicomRegionService = KiteSpringUtils.getBeanHighPriority(IUnicomRegionService.class);
        UnicomRegion unicomRegions = unicomRegionService.getRegion(regionCode);
        String regionName = "";
        if (!KiteObjectUtils.isEmpty(unicomRegions)) {
            regionName = unicomRegions.getRegionName();
        }
        return regionName;
    }

    public static String getRegionNames(List<String> regionCodeList, String separator) {
        if (KiteListUtils.isEmpty(regionCodeList)) {
            return null;
        }
        IUnicomRegionService unicomRegionService = KiteSpringUtils.getBeanHighPriority(IUnicomRegionService.class);
        List<UnicomRegion> unicomRegionList = unicomRegionService.getRegionList(regionCodeList);
        StringBuffer sb = new StringBuffer();
        if(unicomRegionList != null && unicomRegionList.size() > 0) {
            sb.append(unicomRegionList.get(0).getRegionName());
            for (int i = 1; i < unicomRegionList.size(); i++) {
                sb.append(separator).append(unicomRegionList.get(i).getRegionName());
            }
        }
        return sb.toString();
    }

    public static UnicomRegion getRegion(String regionCode) {
        IUnicomRegionService unicomRegionService = KiteSpringUtils.getBeanHighPriority(IUnicomRegionService.class);
        UnicomRegion unicomRegions = unicomRegionService.getRegion(regionCode);
        if (!KiteObjectUtils.isEmpty(unicomRegions)) {
            return unicomRegions;
        }
        return new UnicomRegion();
    }

    public static void initPlatformProvince(KiteAttr attr, String productId) {
        IUnicomRegionService unicomRegionService = KiteSpringUtils.getBeanHighPriority(IUnicomRegionService.class);
        List<UnicomRegion> unicomRegions = unicomRegionService.subRegionFromPlatform(new UnicomRegionQry(productId));
        if (KiteListUtils.isEmpty(unicomRegions)) {
            return;
        }
        List<KiteAttrValue> kiteAttrValues = unicomRegions.stream().map(unicomRegion -> {
            KiteAttrValue kiteAttrValue = new KiteAttrValue();
            kiteAttrValue.setAttrValue(unicomRegion.getRegionCode());
            kiteAttrValue.setAttrValueName(unicomRegion.getRegionName());
            return kiteAttrValue;
        }).collect(Collectors.toList());

        attr.setAttrValues(kiteAttrValues);
    }

    public static void loadPlatformCity(String provinceCode, KiteAttr city, String productId) {
        if (KiteStringUtils.isNotEmpty(provinceCode)) {
            IUnicomRegionService unicomRegionService = KiteSpringUtils.getBeanHighPriority(IUnicomRegionService.class);
            List<UnicomRegion> unicomRegions = unicomRegionService.subRegionFromPlatform(new UnicomRegionQry(provinceCode, "20", productId));
            if (KiteListUtils.isEmpty(unicomRegions)) {
                return;
            }
            List<KiteAttrValue> kiteAttrValues = unicomRegions.stream().map(unicomRegion -> {
                KiteAttrValue kiteAttrValue = new KiteAttrValue();
                kiteAttrValue.setAttrValue(unicomRegion.getRegionCode());
                kiteAttrValue.setAttrValueName(unicomRegion.getRegionName());
                return kiteAttrValue;
            }).collect(Collectors.toList());

            city.setAttrValues(kiteAttrValues);
        }
        else {
            city.setAttrValues(new ArrayList<>());
        }
    }

    public static String getPlatformRegionName(String parentRegionCode, String regionCode, String localtionType, String productId) {
        UnicomRegionService unicomRegionService = KiteSpringUtils.getBeanHighPriority(UnicomRegionService.class);
        if (KiteStringUtils.isEmpty(regionCode)) {
            return "";
        }
        List<UnicomRegion> unicomRegions = unicomRegionService.subRegionFromPlatform(new UnicomRegionQry(parentRegionCode, localtionType, productId));
        String[] regionCodes = KiteStringUtils.split(regionCode, SymbolConsts.COMMA);
        List<String> regionNames = new ArrayList<>();
        for (int i = 0; i < regionCodes.length; i++) {
            String currentRegionCode = regionCodes[i];
            String regionName = unicomRegions.stream()
                .filter(unicomRegion -> currentRegionCode.equals(unicomRegion.getRegionCode())).findAny()
                .map(UnicomRegion::getRegionName).orElse("");
            regionNames.add(regionName);
        }
        return KiteStringUtils.join(regionNames, SymbolConsts.HYPHEN);
    }

    public static void transformAddrCodeToName(String addrFileNames, KiteAttr kiteAttr) {
        if (KiteStringUtils.contains(addrFileNames, kiteAttr.getFieldName())) {
            UnicomRegion unicomRegion = getRegion(kiteAttr.getValue());
            String regionName = unicomRegion.getRegionName();
            if (KiteStringUtils.isNotEmpty(regionName)) {
                kiteAttr.setValueDesc(regionName);
                if (KiteListUtils.isEmpty(kiteAttr.getAttrValues())) {
                    KiteAttrValue kiteAttrValue = new KiteAttrValue();
                    kiteAttrValue.setAttrValue(unicomRegion.getRegionCode());
                    kiteAttrValue.setAttrValueName(unicomRegion.getRegionName());
                    kiteAttr.setAttrValues(Arrays.asList(kiteAttrValue));;
                }
            }
        }
    }

    /**
     * 设置展示并且必填
     *
     * @param inst
     * @param fieldNames
     */
    public static void showAndNonnull(KiteInst inst, String... fieldNames) {
        Arrays.stream(fieldNames)
            .forEach(fieldName -> Optional.ofNullable(inst.getAttr(fieldName)).ifPresent(kiteAttr -> {
                kiteAttr.setShowType(KeyConsts.PROD_ATTR_SHOW_TYPE_M);
                kiteAttr.setIsNull(KeyConsts.IFTRUE_F);
            }));
    }
    /**
     * 设置展示并且必填
     *
     * @param inst
     * @param fieldNames
     */
    public static void showAndNotNull(KiteInst inst, String... fieldNames) {
        Arrays.stream(fieldNames)
            .forEach(fieldName -> Optional.ofNullable(inst.getAttr(fieldName)).ifPresent(kiteAttr -> {
                kiteAttr.setShowType(KeyConsts.PROD_ATTR_SHOW_TYPE_D);
                kiteAttr.setIsNull(KeyConsts.IFTRUE_F);
            }));
    }

    /**
     * 设置展示并且必填
     *
     * @param inst
     * @param fieldNames
     */
    public static void showForDAndNull(KiteInst inst, String... fieldNames) {
        Arrays.stream(fieldNames)
            .forEach(fieldName -> Optional.ofNullable(inst.getAttr(fieldName)).ifPresent(kiteAttr -> {
                kiteAttr.setShowType(KeyConsts.PROD_ATTR_SHOW_TYPE_D);
                kiteAttr.setIsNull(KeyConsts.IFTRUE_T);
            }));
    }

    /**
     * 设置展示并且必填
     *
     * @param inst
     * @param fieldNames
     */
    public static void showAndNull(KiteInst inst, String... fieldNames) {
        Arrays.stream(fieldNames)
            .forEach(fieldName -> Optional.ofNullable(inst.getAttr(fieldName)).ifPresent(kiteAttr -> {
                kiteAttr.setShowType(KeyConsts.PROD_ATTR_SHOW_TYPE_M);
                kiteAttr.setIsNull(KeyConsts.IFTRUE_T);
            }));
    }
    /**
     * 设置隐藏并且非必填
     *
     * @param inst
     * @param fieldNames
     */
    public static void hideAndNullable(KiteInst inst, String... fieldNames) {
        Arrays.stream(fieldNames)
            .forEach(fieldName -> Optional.ofNullable(inst.getAttr(fieldName)).ifPresent(kiteAttr -> {
                kiteAttr.setShowType(KeyConsts.PROD_ATTR_SHOW_TYPE_E);
                kiteAttr.setIsNull(KeyConsts.IFTRUE_T);
            }));
    }

    /**
     * 设置隐藏并且非必填
     *
     * @param inst
     * @param fieldNames
     */
    public static void hideAndNull(KiteInst inst, String... fieldNames) {
        Arrays.stream(fieldNames)
            .forEach(fieldName -> Optional.ofNullable(inst.getAttr(fieldName)).ifPresent(kiteAttr -> {
                kiteAttr.setShowType(KeyConsts.PROD_ATTR_SHOW_TYPE_H);
                kiteAttr.setIsNull(KeyConsts.IFTRUE_T);
            }));
    }

    /**
     * 设置属性showType
     * @param inst
     * @param showType
     * @param fieldNames
     */
    public static void setShowType(KiteInst inst, String showType, String... fieldNames) {
        Arrays.stream(fieldNames).forEach(fieldName -> Optional.ofNullable(inst.getAttr(fieldName)).ifPresent(kiteAttr -> kiteAttr.setShowType(showType)));
    }

    public static void hidden5GCommonAttr(String sceneInstId, String custId, CommonAttrVO commonAttr) {
        IQuerySceneInstService querySceneInstService = SpringUtil.getBean(IQuerySceneInstService.class);
        IOperateSceneInstService operateSceneInstService = SpringUtil.getBean(IOperateSceneInstService.class);
        KiteSceneInst kiteSceneInst = querySceneInstService.getSceneInst(sceneInstId);
        KiteOfferInst offerInst = querySceneInstService.getOfferInst(custId, kiteSceneInst.getRootInstId());
        String cateId = "";
        if (!KiteObjectUtils.isEmpty(offerInst)) {
            cateId = offerInst.getAttrValue("cateId");
        }
        if (KiteStringUtils.equals(cateId, "2000966")) {
            commonAttr.setShowType("E");
            KiteAttr kiteAttr = querySceneInstService.getCommonAttr(sceneInstId, commonAttr.getFieldName());
            kiteAttr.setShowType("E");
            operateSceneInstService.setCommonAttr(sceneInstId, kiteAttr);
        }
    }

    public static void hiddenOrDisplayProdAttr(String sceneInstId, KiteInst prodInst, KiteAttr kiteAttr, String showType, String value) {
        OperateInstAttrService operateInstAttrService = SpringUtil.getBean(OperateInstAttrService.class);
        kiteAttr.setShowType(showType);
        operateInstAttrService.setAttrValue(prodInst, kiteAttr.getFieldName(), value, sceneInstId, null);
    }

    public static void setSpecialAttrValue(String sceneInstId, String custId, CommonAttrVO commonAttr, String className) {
        IQuerySceneInstService querySceneInstService = SpringUtil.getBean(IQuerySceneInstService.class);
        String serviceOfferId = querySceneInstService.getSceneInst(sceneInstId).getServiceOfferId();
        String fieldName = commonAttr.getFieldName();
        KiteSceneInst kiteSceneInst = querySceneInstService.getSceneInst(sceneInstId);
        KiteOfferInst offerInst = querySceneInstService.getOfferInst(custId, kiteSceneInst.getRootInstId());
        String cateId = Optional.ofNullable(offerInst.getAttrValue("cateId")).orElse(null);
        List<DcPublic> dcPublicList = DcPublicCache.getByPkey("21041310271", className);
        if (KiteListUtils.isNotEmpty(dcPublicList)) {
            DcPublic dcPublicTarget = dcPublicList.stream().filter(dcPublic -> (KiteStringUtils.equals(dcPublic.getCodea(), fieldName) &&
                KiteStringUtils.equals(dcPublic.getCodec(), cateId) &&
                KiteStringUtils.equals(dcPublic.getCoded(), serviceOfferId))).findFirst().orElse(null);
            if (Objects.nonNull(dcPublicTarget)) {
                commonAttr.setValue(dcPublicTarget.getCodeb());
                commonAttr.setDefaultValue(dcPublicTarget.getCodeb());
                commonAttr.setValueDesc(getAttrValueDesc(sceneInstId, commonAttr, dcPublicTarget.getCodeb()));
            }
        }
    }

    private static String getAttrValueDesc(String sceneInstId, CommonAttrVO commonAttr, String value) {
        List<StaticAttrDO> attrValues = commonAttr.getAttrValues();
        String desc = "";
        if (KiteListUtils.isNotEmpty(attrValues)) {
            StaticAttrDO targetAttr = attrValues.stream().filter(attrValue -> KiteStringUtils.equals(attrValue.getAttrValue(), value)).findFirst().orElse(null);
            desc = Optional.ofNullable(targetAttr).map(attr -> attr.getAttrValueDesc()).orElse("");
        } else {
            IQuerySceneInstService querySceneInstService = SpringUtil.getBean(IQuerySceneInstService.class);
            if (KiteStringUtils.equalsAny(commonAttr.getFieldName(), LocalKeyConsts.PRODUCT_LINE_NEW, LocalKeyConsts.PRODUCT_LINE)) {
                // 取行业值
                KiteAttr kiteAttr = querySceneInstService.getCommonAttr(sceneInstId, LocalKeyConsts.INDUSTRY_NEW);
                if (Objects.isNull(kiteAttr)) {
                    querySceneInstService.getCommonAttr(sceneInstId, LocalKeyConsts.INDUSTRY);
                }
                if (Objects.nonNull(kiteAttr)) {
                    List<KiteAttrValue> productLineAttrList = LocalIndustryAttrHelper.loadProductLine(kiteAttr.getValue());
                    if (KiteListUtils.isNotEmpty(productLineAttrList)) {
                        KiteAttrValue kiteAttrValue = productLineAttrList.stream().filter(attrValue -> KiteStringUtils.equals(attrValue.getAttrValue(), value)).findFirst().orElse(null);
                        commonAttr.setAttrValues(KiteBeanUtils.copyPropsForList(productLineAttrList, StaticAttrDO.class));
                        desc = Optional.ofNullable(kiteAttrValue).map(attr -> attr.getAttrValueDesc()).orElse("");
                    }
                }
            }
            if (KiteStringUtils.equalsAny(commonAttr.getFieldName(), LocalKeyConsts.SEGMENT_KEY_PRODUCT_NEW, LocalKeyConsts.SEGMENT_KEY_PRODUCT)) {
                // 取产品线
                KiteAttr ProdLineAttr = querySceneInstService.getCommonAttr(sceneInstId, LocalKeyConsts.PRODUCT_LINE_NEW);
                if (Objects.isNull(ProdLineAttr)) {
                    querySceneInstService.getCommonAttr(sceneInstId, LocalKeyConsts.PRODUCT_LINE);
                }
                if (Objects.nonNull(ProdLineAttr)) {
                    List<KiteAttrValue> segmentAttrList = LocalIndustryAttrHelper.loadProductLine(ProdLineAttr.getValue());
                    if (KiteListUtils.isNotEmpty(segmentAttrList)) {
                        KiteAttrValue kiteAttrValue = segmentAttrList.stream().filter(attrValue -> KiteStringUtils.equals(attrValue.getAttrValue(), value)).findFirst().orElse(null);
                        commonAttr.setAttrValues(KiteBeanUtils.copyPropsForList(segmentAttrList, StaticAttrDO.class));
                        desc = Optional.ofNullable(kiteAttrValue).map(attr -> attr.getAttrValueDesc()).orElse("");
                    }
                }
            }
        }
        return desc;
    }

    /**
     * 从省-市-县中文中获取地市编码
     * @author zhang.song
     * @date 2021-08-03 10:43
     * @param regionName 中文名称，以'-'分隔
     * @param prodId （可为null）产品编码，用于区分是否包含国际区域，为空则默认不包含国际区域
     * @return java.lang.String
     */
    public static String getCityNameFromRegionName(String regionName, String prodId) {
        if(KiteStringUtils.isNotEmpty(regionName) && RegexUtils.find(RegexUtils.ISCHINESE, regionName)) {
            String[] names = regionName.split(SymbolConsts.HYPHEN);
            IUnicomRegionService unicomRegionService = KiteSpringUtils.getBeanHighPriority(IUnicomRegionService.class);

            List<String> codeList = new ArrayList<>();
            List<UnicomRegion> unicomRegions;
            for (int i = 0; i < names.length && i < 2; i++) {
                unicomRegions = unicomRegionService.subRegionFromPlatform(new UnicomRegionQry((i==0?null:codeList.get(i-1)), String.valueOf(i*10+10), prodId));
                if(KiteListUtils.isEmpty(unicomRegions)) {
                    break;
                }

                String regionCode = unicomRegions.stream().filter(unicomRegion ->
                    KiteStringUtils.isEqual(names[codeList.size()], unicomRegion.getRegionName())).findAny().map(UnicomRegion::getRegionCode).orElse(null);

                if(KiteStringUtils.isEmpty(regionCode)) {
                    break;
                }
                codeList.add(regionCode);
            }

            if(codeList.size() > 0) {
                return codeList.get(codeList.size() - 1);
            }
        }
        return null;
    }

    /**
     * 将省市县编码转为中文
     * @author zhang.song
     * @date 2021-08-06 17:54
     * @param regionCode 编码，以','分隔
     * @param prodId （可为null）产品编码，用于区分是否包含国际区域，为空则默认不包含国际区域
     * @return java.lang.String
     */
    public static String transformRegionCodeToName(String regionCode, String prodId, String separator) {
        if(KiteStringUtils.isNotEmpty(regionCode)) {
            String[] codes = regionCode.split(SymbolConsts.COMMA);
            IUnicomRegionService unicomRegionService = KiteSpringUtils.getBeanHighPriority(IUnicomRegionService.class);

            List<String> nameList = new ArrayList<>();
            List<UnicomRegion> unicomRegions;
            for (int i = 0; i < codes.length && i < 3; i++) {
                unicomRegions = unicomRegionService.subRegionFromPlatform(new UnicomRegionQry((i==0?null:codes[i-1]), String.valueOf(i*10+10), prodId));
                if(KiteListUtils.isEmpty(unicomRegions)) {
                    break;
                }

                String regionName = unicomRegions.stream().filter(unicomRegion ->
                    KiteStringUtils.isEqual(codes[nameList.size()], unicomRegion.getRegionCode())).findAny().map(UnicomRegion::getRegionName).orElse(null);

                if(KiteStringUtils.isEmpty(regionName)) {
                    break;
                }
                nameList.add(regionName);
            }

            separator = separator == null ? SymbolConsts.HYPHEN : separator;
            return KiteStringUtils.join(nameList, separator);
        }
        return null;
    }
}
